﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Diagnostics;
using APC.Common; //Database Handling

namespace APC
{
    class Tag
    {

        #region Properties

        public string OrderNumber
        {
            set { _OrderNumber = value;   }
        }
        private string _OrderNumber;

        public string OrderId
        {
            set { _OrderId = value; }
        }
        private string _OrderId = "";

        public string BatchId
        {
            set { _BatchId = value; }
        }
        private string _BatchId = "";

        public string BatchNumber
        {
            set { _BatchNumber = value; }
        }
        private string _BatchNumber = "";

        /// <summary>
        /// Total number of batches in order
        /// </summary>
        public int TotalBatchCount
        {
            set { _TotalBatchCount = value; }
        }
        private int _TotalBatchCount = 0;

        /// <summary>
        /// Number of present batch
        /// </summary>
        public int BatchCounter
        {
            set { _BatchCounter = value; }
        }
        private int _BatchCounter = 0;

        public int PacketSize
        {
            set { _PacketSize = value; }
            get { return _PacketSize; }
        }
        private int _PacketSize = 0;

        public string RecipeNumber
        {
            set { _RecipeNumber = value; }
        }
        private string _RecipeNumber = "";

        public string RecipeName
        {
            set { _RecipeName = value; }
        }
        private string _RecipeName = "";

        /// <summary>
        /// Location identifier for equipment
        /// </summary>
        public int TagListeGroupId
        {
            set { _TagListeGroupId = value; }
        }
        private int _TagListeGroupId = 0;

        /// <summary>
        /// Commaseparated list of storage Id's (Location.Id)
        /// </summary>
        public string StorageSiloArray
        {
            set { _StorageSiloArray = value; }
        }
        private string _StorageSiloArray;

        /// <summary>
        /// List of all TagValuePairs is returned to each batch object
        /// </summary>
        public List<TagValuePair> TagValuePairs
        {
            get { return _TagValuePairs; }
            set { _TagValuePairs = value; }
        }
        List<TagValuePair> _TagValuePairs = null;

        public List<TagListe> TagList
        {
            get { return _TagList; }
            set { _TagList = value; }
        }
        List<TagListe> _TagList = null;

        #endregion

        #region Declarations

        private List<APC.Common.TagListe> TagListFull; //Holds full TagName list to avoid reload on multiple runs (cache)
        private DataHandlingDataContext ctx;
        private Dictionary<int, int> dicTagGroups;

        //private bool TagGroupHeader3001Set = false;
        //private bool TagGroupHeader3002Set = false;
        //private bool TagGroupHeader3003Set = false;
        //private bool TagGroupHeader3004Set = false;
        //private bool TagGroupHeader7001Set = false;
     

        #endregion

        #region Constructor

        /// <summary>
        /// Constructor
        /// </summary>
        public Tag()
        {
          
        }

        public Tag(bool LoadLists)
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);
            LoadTagList();
        }

        #endregion

        #region Public Methods

        /// <summary>
        /// Set tagvalues as header for each scale
        /// </summary>
        public void SetTagHeader()
        {
            if (_TagValuePairs == null)
            {
                this._TagValuePairs = new List<TagValuePair>();
            }

            if (dicTagGroups == null)
            {
                dicTagGroups = new Dictionary<int, int>();
            }


            //CHECK if database flags is set correct for new tags! like:  AddToTransaction = 1, ToZenonRead = 0
            LoadTagValuePair("SCALE_ORDER_ID", _OrderId);
            LoadTagValuePair("SCALE_BATCH_ID", _BatchCounter.ToString());
            LoadTagValuePair("SCALE_ORDER_NO", _OrderNumber);
            LoadTagValuePair("SCALE_BATCH_NO", _BatchNumber);
            LoadTagValuePair("APC_PLC_SCALE_NO_OF_BATCH", _TotalBatchCount.ToString());
            LoadTagValuePair("SCALE_RECIPE_NO", _RecipeNumber);
            LoadTagValuePair("SCALE_RECIPE_NAME", _RecipeName);
            LoadTagValuePair("APC_PLC_SCALE_PACKET_SIZE", _PacketSize.ToString()); //Number of silos in array
            LoadTagValuePair("APC_PLC_SCALE_DEST_SILO_NO", _StorageSiloArray); //Array of storage silo's
        }

        //public void xTagGroup(int GroupNo, APC.Common.GetRecipeIngredientsResult rp, Decimal amount)
        //{

        //    switch (GroupNo)
        //    {
        //        case 3001: //Scale 1
        //            if (TagGroupHeader3001Set == false) //Only set header once per silo
        //            {
        //                //SetTagHeader();
        //                TagGroupHeader3001Set = true;
        //            }
        //            break;

        //        case 3002: // 
        //            if (TagGroupHeader3002Set == false) //Only set header once per silo
        //            {
        //                SetTagHeader();
        //                TagGroupHeader3002Set = true;
        //            }
        //            break;

        //        case 3003:
        //            if (TagGroupHeader3003Set == false) //Only set header once per silo
        //            {
        //                SetTagHeader();
        //                TagGroupHeader3003Set = true;
        //            }
        //            break;

        //        case 3004:
        //            if (TagGroupHeader3004Set == false) //Only set header once per silo
        //            {
        //                SetTagHeader();
        //                TagGroupHeader3004Set = true;
        //            }
        //            break;

        //        case 7001:
        //            if (TagGroupHeader7001Set == false) //Only set header once per silo
        //            {
        //                SetTagHeader();
        //                TagGroupHeader7001Set = true;
        //            }
        //            break;

        //    }


            //string Location = rp.LocationPosition.ToString(); //Silo index

            //LoadTagValuePair("APC_PLC_SCALE_SILO_NO_" + SiloIndex3001.ToString(), rp.LocationPosition.ToString());
            //LoadTagValuePair("APC_PLC_SCALE_SILO_NO_" + SiloIndex3001.ToString() + "_SP", amount.ToString());
            //LoadTagValuePair("APC_PLC_SCALE_SILO_NO_" + SiloIndex3001.ToString() + "_TOL_PCT", rp.ToleranceProcent.ToString());
            ////LoadTagValuePair("APC_PLC_SCALE_SILO_NO_" + SiloIndex3001.ToString() + "_TOL_KG", "0");

            //SiloIndex3001 += 1;
       // }

        /// <summary>
        /// Returns the TagId for a TagName (VarName)
        /// </summary>
        /// <param name="TagName"></param>
        /// <returns></returns>
        public int FindTagIdOnTagName(string TagName)
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            var query = ctx.TagListes.FirstOrDefault(x => x.VarName.EndsWith(TagName));
            int TagId = -1;

            if (query != null)
            {
                TagId = query.Id;
            }

            return TagId;
        }

        /// <summary>
        /// 
        /// </summary>
        public void TagGroupSilo(int TagListGroupId, APC.RawMaterials rp, Decimal amount)
        {

            if (!dicTagGroups.ContainsKey(TagListGroupId))
            {
                dicTagGroups.Add(TagListGroupId, 0);
            }
            else
            {
                dicTagGroups[TagListGroupId] = dicTagGroups[TagListGroupId] + 1;
            }

            LoadTagValuePair("APC_PLC_SCALE_SILO_NO_" + dicTagGroups[TagListGroupId].ToString(), rp.LocationPosition.ToString());
            LoadTagValuePair("APC_PLC_SCALE_SILO_NO_" + dicTagGroups[TagListGroupId].ToString() + "_SP", amount.ToString());
            LoadTagValuePair("APC_PLC_SCALE_SILO_NO_" + dicTagGroups[TagListGroupId].ToString() + "_TOL_PCT", rp.Tolerance.ToString());
        }

        #endregion

        #region Private Methods

        /// <summary>
        /// Loads pair of TagNames and its value
        /// </summary>
        /// <param name="TagNamePart">Search on part of tagname to find its Id</param>
        /// <param name="TagValue">The value to send with tagname</param>
        /// <param name="BatchCountId">Each TagName + Value is related to a BatchCountId (1, 2, 3 ...)</param>
        /// <returns></returns>
        private void LoadTagValuePair(String TagNamePart, String TagValue)
        {

            TagValuePair tvp = null;

            //Fill List with all tags on first run...cache
            if (this.TagListFull == null)
            {
                if (ctx == null) 
                {
                    ctx = new DataHandlingDataContext(new Data().ConnectionString); 
                }

                var q = from var3 in ctx.TagListes.Where(str => str.AddToTransaction == 1 && str.ToZenonRead == 0)
                        select var3;
                TagListFull = q.ToList<APC.Common.TagListe>();
            }

            //Filter on part of Tagname
            var query = TagListFull.FirstOrDefault(x => x.VarName.EndsWith(TagNamePart));

            if (query != null)
            {
                tvp = new TagValuePair();
                tvp.TagListeId = query.Id;
                tvp.TagName = query.VarName; //TODO: Not needed after test!
                tvp.TagValue = TagValue.Trim();
                tvp.TagListeGroupId = _TagListeGroupId;

                this._TagValuePairs.Add(tvp);

                //Debug.WriteLine(tvp.TagName + ": " + tvp.TagValue);
            }
            else
            {
                new Exception("Error in LoadTagValuePair: " + TagNamePart);
            }

 

           
        }

        private void LoadTagList()
        {

                var q = from var3 in ctx.TagListes.Where(str => str.AddToTransaction == 1 && str.ToZenonRead == 0)
                        select var3;

                TagList = q.ToList<APC.Common.TagListe>();
        }

        /// <summary>
        /// Loads list of TagListGroups for silos (GroupNo startswith "300")
        /// </summary>
        public List<TagListGroup> LoadTagListGroup()
        {
            ctx = new DataHandlingDataContext(new Data().ConnectionString);

            List<TagListGroup> lst = null;

            var q = from tlg in ctx.TagListGroups.Where(x => x.GroupNo.ToString().StartsWith("300") || x.GroupNo.ToString().StartsWith("700"))
                    select tlg;

            lst = q.ToList<APC.Common.TagListGroup>();

            return lst;
        }

        #endregion
    }
}
